package main

import "fmt"

//如何向func传递默认值

type dialOption struct { // 数据结构体
	Username string
	Password string
	Service  string
}

type DialOption interface { // 结构体接口
	apply(*dialOption)
}

type funcOption struct { // 结构体接口功能选项
	f func(*dialOption)
}

func (fdo *funcOption) apply(do *dialOption) { // 应用方法，需要传入数据结构体的参数用于应用结构体接口功能选项的f方法
	fdo.f(do)
}

// 工厂模式 相当于构造函数
func newFuncOption(f func(*dialOption)) *funcOption {
	return &funcOption{
		f: f,
	}
}

// 测试用例：通过构造函数的方法传值

func withUserName(s string) DialOption {
	return newFuncOption(func(o *dialOption) {
		o.Username = s
	})
}

func withPasswordd(s string) DialOption {
	return newFuncOption(func(o *dialOption) {
		o.Password = s
	})
}

func withService(s string) DialOption {
	return newFuncOption(func(o *dialOption) {
		o.Service = s
	})
}

//默认参数
func defaultOptions() dialOption {
	return dialOption{
		Service: "test",
	}
}

type clientConn struct { // 客户端连接结构体
	timeout int
	dopts   dialOption
}

func NewClient(address string, opts ...DialOption) { // 接收任意个结构体接口
	cc := &clientConn{
		timeout: 30,
		dopts:   defaultOptions(),
	}
	//循环调用opts
	for _, opt := range opts {
		opt.apply(&cc.dopts)
	}

	//fmt.Printf("%+v\n",cc.dopts)
	fmt.Println(cc.dopts)
}

func main() {
	NewClient("127.0.0.1", withPasswordd("654321"), withService("habox"))
	NewClient("127.0.0.1", withService("habox"))
}
